// SPDX-License-Identifier: GPL-2.0
/*
 * BUDDY: SET MEMORY POLICY
 *
 * (C) 2024.05.01 BuddyZhang1 <buddy.zhang@aliyun.com>
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
/* NUMA header with -lnuma */
#include <numa.h>
#include <numaif.h>

#define MAP_VADDR	0x600000000
#define MAP_SIZE	0x4000
#define NODE10		(1 << 10)
#define NODE0		(1 << 0)
#define NODE1		(1 << 1)
#define NODE2		(1 << 2)
#define MAX_NODES	16

int main()
{
	unsigned long nodemask = NODE1 | NODE10 | NODE2;
	void *mem;

	/* SET MEMORY POLICY */
	set_mempolicy(MPOL_INTERLEAVE, &nodemask, MAX_NODES);

	/* ALLOC MEMORY */
	mem = mmap((void *)MAP_VADDR, MAP_SIZE,
		   PROT_READ | PROT_WRITE,
		   MAP_ANONYMOUS | MAP_PRIVATE,
		   -1,
		   0);
	if (mem == MAP_FAILED) {
		printf("ERROR: ALLOC MEMORY FAILED.\n");
		return -1;
	}

	/* ACCESS */
	*(char *)((char *)mem + 4096 * 0) = 'C'; /* NODE1 */
	*(char *)((char *)mem + 4096 * 1) = 'C'; /* NODE2 */
	*(char *)((char *)mem + 4096 * 2) = 'C'; /* NODE1 */
	*(char *)((char *)mem + 4096 * 3) = 'C'; /* NODE2 */

	printf("ANONYMOUS MEMORY: %#lx %c\n", 
			(unsigned long)mem, *(char *)mem);

	/* RECLAIM */
	munmap(mem, MAP_SIZE);

	return 0;
}
